#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
User Plane Signaling Analysis Tool - Main Program
用户面信令分析工具 - 主程序

功能：
1. 自动检测data文件夹中的pcap文件
2. 调用pcap解析脚本生成JSON文件
3. 调用JSON分析脚本生成分析结果
4. 调用网页生成脚本创建最终报告
5. 提供完整的分析流程

作者：Falcomm自研团队
版本：1.0
日期：2025-08-15
"""

import os
import sys
import json
import time
import subprocess
from pathlib import Path
from datetime import datetime

class SignalingAnalysisTool:
    def __init__(self):
        self.project_root = Path(__file__).parent
        self.data_user_dir = self.project_root / "data_user"
        self.data_control_dir = self.project_root / "data_control"
        self.json_dir = self.project_root / "json"
        self.scripts_dir = self.project_root / "scripts"
        self.styles_dir = self.project_root / "styles"
        self.docs_dir = self.project_root / "docs"
        
        # 确保目录存在
        self._ensure_directories()
        
        # 脚本路径
        self.pcap_parser = self.scripts_dir / "pcap_parser.py"
        self.json_analyzer = self.scripts_dir / "json_analyzer.py"
        self.web_generator = self.scripts_dir / "web_generator.py"
        self.user_plane_web_generator = self.scripts_dir / "user_plane_web_generator.py"
        self.control_plane_web_generator = self.scripts_dir / "control_plane_web_generator.py"
        self.control_analyzer = self.scripts_dir / "control_plane_analyzer.py"
        
        print("User Plane Signaling Analysis Tool Started")
        print(f"Project Root: {self.project_root}")
        print(f"User Data Directory: {self.data_user_dir}")
        print(f"Control Data Directory: {self.data_control_dir}")
        print(f"JSON Directory: {self.json_dir}")
        print(f"Scripts Directory: {self.scripts_dir}")
        print(f"Styles Directory: {self.styles_dir}")
        print(f"Docs Directory: {self.docs_dir}")
        print("-" * 60)

    def _ensure_directories(self):
        """确保所有必要的目录都存在"""
        for directory in [self.data_user_dir, self.data_control_dir, self.json_dir, self.scripts_dir, self.styles_dir, self.docs_dir]:
            directory.mkdir(exist_ok=True)

    def scan_pcap_files(self):
        """扫描用户面和控制面数据目录中的pcap文件"""
        user_pcap_files = list(self.data_user_dir.glob("*.pcap"))
        control_pcap_files = list(self.data_control_dir.glob("*.pcap"))
        
        all_pcap_files = []
        
        # 处理用户面数据
        if user_pcap_files:
            print(f"Found {len(user_pcap_files)} user plane pcap files:")
            for pcap_file in user_pcap_files:
                print(f"  [USER] {pcap_file.name}")
                all_pcap_files.append(("user", pcap_file))
        
        # 处理控制面数据
        if control_pcap_files:
            print(f"Found {len(control_pcap_files)} control plane pcap files:")
            for pcap_file in control_pcap_files:
                print(f"  [CONTROL] {pcap_file.name}")
                all_pcap_files.append(("control", pcap_file))
        
        if not all_pcap_files:
            print("No .pcap files found in data directories")
            print("Please place pcap files in the data_user or data_control directory")
            return []
        
        return all_pcap_files

    def check_scripts(self):
        """检查必要的脚本文件是否存在"""
        required_scripts = [
            self.pcap_parser, 
            self.json_analyzer, 
            self.web_generator,
            self.user_plane_web_generator,
            self.control_plane_web_generator,
            self.control_analyzer
        ]
        missing_scripts = []
        
        for script in required_scripts:
            if not script.exists():
                missing_scripts.append(script.name)
        
        if missing_scripts:
            print(f"Missing required script files: {', '.join(missing_scripts)}")
            print("Please ensure all script files are in the scripts directory")
            return False
        
        print("All required script files check passed")
        return True

    def run_pcap_parser(self, pcap_file):
        """运行pcap解析脚本"""
        print(f"\nStarting pcap file parsing: {pcap_file.name}")
        
        try:
            # 调用pcap解析脚本
            result = subprocess.run([
                sys.executable, str(self.pcap_parser),
                str(pcap_file),
                str(self.json_dir)
            ], capture_output=True, text=True, cwd=self.project_root)
            
            if result.returncode == 0:
                print(f"Pcap file parsing successful: {pcap_file.name}")
                return True
            else:
                print(f"Pcap file parsing failed: {pcap_file.name}")
                print(f"Error: {result.stderr}")
                return False
                
        except Exception as e:
            print(f"Error running pcap parser script: {e}")
            return False

    def run_json_analyzer(self, json_file):
        """运行JSON分析脚本"""
        print(f"\nStarting JSON file analysis: {json_file.name}")
        
        try:
            # 调用JSON分析脚本
            result = subprocess.run([
                sys.executable, str(self.json_analyzer),
                str(json_file),
                str(self.docs_dir)
            ], capture_output=True, text=True, cwd=self.project_root)
            
            if result.returncode == 0:
                print(f"JSON file analysis successful: {json_file.name}")
                return True
            else:
                print(f"JSON file analysis failed: {json_file.name}")
                print(f"Error: {result.stderr}")
                return False
                
        except Exception as e:
            print(f"Error running JSON analyzer script: {e}")
            return False

    def run_web_generator(self, analysis_data):
        """运行网页生成脚本"""
        print(f"\nStarting analysis webpage generation")
        
        try:
            # 调用网页生成脚本
            result = subprocess.run([
                sys.executable, str(self.web_generator),
                str(self.docs_dir),
                str(self.styles_dir),
                str(self.project_root)
            ], capture_output=True, text=True, cwd=self.project_root)
            
            if result.returncode == 0:
                print("Analysis webpage generation successful")
                return True
            else:
                print("Analysis webpage generation failed")
                print(f"Error: {result.stderr}")
                return False
                
        except Exception as e:
            print(f"Error running web generator script: {e}")
            return False

    def run_user_plane_web_generator(self):
        """运行用户面网页生成脚本"""
        print(f"\nStarting user plane webpage generation")
        
        try:
            # 调用用户面网页生成脚本
            result = subprocess.run([
                sys.executable, str(self.user_plane_web_generator),
                str(self.docs_dir),
                str(self.styles_dir),
                str(self.project_root)
            ], capture_output=True, text=True, cwd=self.project_root)
            
            if result.returncode == 0:
                print("User plane webpage generation successful")
                return True
            else:
                print("User plane webpage generation failed")
                print(f"Error: {result.stderr}")
                return False
                
        except Exception as e:
            print(f"Error running user plane web generator script: {e}")
            return False

    def run_control_plane_web_generator(self):
        """运行控制面网页生成脚本"""
        print(f"\nStarting control plane webpage generation")
        
        try:
            # 调用控制面网页生成脚本
            result = subprocess.run([
                sys.executable, str(self.control_plane_web_generator),
                str(self.docs_dir),
                str(self.styles_dir),
                str(self.project_root)
            ], capture_output=True, text=True, cwd=self.project_root)
            
            if result.returncode == 0:
                print("Control plane webpage generation successful")
                return True
            else:
                print("Control plane webpage generation failed")
                print(f"Error: {result.stderr}")
                return False
                
        except Exception as e:
            print(f"Error running control plane web generator script: {e}")
            return False

    def run_control_plane_analyzer(self, control_files):
        """运行控制面分析脚本"""
        print(f"\nStarting control plane analysis for {len(control_files)} files")
        
        try:
            # 准备控制面文件路径
            control_file_paths = [str(pcap_file) for plane_type, pcap_file in control_files]
            
            # 外部大模型分析结果路径（可选）
            ziyan_analysis_path = self.project_root.parent / "自研大模型分析报告"
            
            # 调用控制面分析脚本
            result = subprocess.run([
                sys.executable, str(self.control_analyzer),
                *control_file_paths,
                str(self.docs_dir),
                "--ziyan-analysis", str(ziyan_analysis_path)
            ], capture_output=True, text=True, cwd=self.project_root)
            
            if result.returncode == 0:
                print(f"Control plane analysis successful")
                return True
            else:
                print(f"Control plane analysis failed")
                print(f"Error: {result.stderr}")
                print(f"Output: {result.stdout}")
                return False
                
        except Exception as e:
            print(f"Error running control plane analyzer script: {e}")
            return False

    def generate_summary_report(self, pcap_files, total_success_count, user_success_count=0, control_success_count=0):
        """生成总结报告"""
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        
        # 统计用户面和控制面文件数量
        user_files = [(plane_type, pcap_file) for plane_type, pcap_file in pcap_files if plane_type == "user"]
        control_files = [(plane_type, pcap_file) for plane_type, pcap_file in pcap_files if plane_type == "control"]
        
        summary = f"""
# Signaling Analysis Tool - Analysis Report

## Analysis Time
{timestamp}

## Analysis Results
- Total pcap files: {len(pcap_files)}
- User plane files: {len(user_files)}
- Control plane files: {len(control_files)}
- Successfully analyzed: {total_success_count}
- User plane success: {user_success_count}
- Control plane success: {control_success_count}
- Failed: {len(pcap_files) - total_success_count}

## Generated Files
- JSON files: {self.json_dir}
- Analysis documents: {self.docs_dir}
- Analysis webpage: {self.project_root / "sidebar_analysis.html"}

## Usage Instructions
1. Place user plane pcap files in the data_user directory
2. Place control plane pcap files in the data_control directory
3. Run the main program: python main.py
4. View the generated analysis results

## Notes
- Ensure all dependencies are installed
- Check script file permissions
- Review error logs for troubleshooting
- User plane and control plane analysis are processed independently
"""
        
        summary_file = self.project_root / "analysis_summary.md"
        with open(summary_file, 'w', encoding='utf-8') as f:
            f.write(summary)
        
        print(f"\nSummary report generated: {summary_file}")

    def run_analysis(self):
        """运行完整的分析流程"""
        print("\n" + "="*60)
        print("Starting Signaling Analysis Process")
        print("="*60)
        
        # 1. 检查脚本文件
        if not self.check_scripts():
            return False
        
        # 2. 扫描pcap文件
        pcap_files = self.scan_pcap_files()
        if not pcap_files:
            return False
        
        # 3. 分别处理用户面和控制面数据
        user_success_count = 0
        control_success_count = 0
        
        # 按类型分组处理
        user_files = [(plane_type, pcap_file) for plane_type, pcap_file in pcap_files if plane_type == "user"]
        control_files = [(plane_type, pcap_file) for plane_type, pcap_file in pcap_files if plane_type == "control"]
        
        # 处理用户面数据
        if user_files:
            print(f"\n{'='*50}")
            print("PROCESSING USER PLANE SIGNALING")
            print(f"{'='*50}")
            user_success_count = self._process_plane_files("user", user_files)
        
        # 处理控制面数据
        if control_files:
            print(f"\n{'='*50}")
            print("PROCESSING CONTROL PLANE SIGNALING")
            print(f"{'='*50}")
            control_success_count = self._process_plane_files("control", control_files)
        
        # 4. 生成网页报告
        total_success = user_success_count + control_success_count
        if total_success > 0:
            print(f"\n{'='*40}")
            print("Generating analysis webpages")
            print(f"{'='*40}")
            
            # 生成用户面报告
            if user_success_count > 0:
                self.run_user_plane_web_generator()
            
            # 生成控制面报告
            if control_success_count > 0:
                self.run_control_plane_web_generator()
        
        # 5. 生成总结报告
        self.generate_summary_report(pcap_files, total_success, user_success_count, control_success_count)
        
        print(f"\n{'='*60}")
        print(f"Analysis process completed!")
        print(f"User plane processed: {user_success_count}/{len(user_files)} files")
        print(f"Control plane processed: {control_success_count}/{len(control_files)} files")
        print(f"Total successfully processed: {total_success}/{len(pcap_files)} files")
        print(f"Results location: {self.project_root}")
        print(f"{'='*60}")
        
        return total_success > 0
    
    def _process_plane_files(self, plane_type, files):
        """处理特定平面的文件"""
        success_count = 0
        
        if plane_type == "control":
            # 控制面特殊处理：先解析所有文件，然后进行合并分析
            print(f"Processing {len(files)} control plane files for merged analysis")
            
            # 1. 解析所有控制面文件
            parsed_files = []
            for plane_type, pcap_file in files:
                print(f"\n{'='*40}")
                print(f"Parsing {plane_type.upper()} plane file: {pcap_file.name}")
                print(f"{'='*40}")
                
                if self.run_pcap_parser(pcap_file):
                    parsed_files.append((plane_type, pcap_file))
                else:
                    print(f"Pcap parsing failed for {pcap_file.name}")
            
            # 2. 运行控制面专门分析
            if parsed_files:
                if self.run_control_plane_analyzer(parsed_files):
                    success_count = len(parsed_files)
                    print(f"Control plane merged analysis completed for {len(parsed_files)} files")
                else:
                    print("Control plane merged analysis failed")
            else:
                print("No control plane files were successfully parsed")
        
        else:
            # 用户面正常处理
            for plane_type, pcap_file in files:
                print(f"\n{'='*40}")
                print(f"Processing {plane_type.upper()} plane file: {pcap_file.name}")
            print(f"{'='*40}")
            
            # 解析pcap文件
            if self.run_pcap_parser(pcap_file):
                # 查找生成的JSON文件
                json_file = self.json_dir / f"{pcap_file.stem}.json"
                if json_file.exists():
                    # 分析JSON文件
                    if self.run_json_analyzer(json_file):
                        success_count += 1
                    else:
                        print(f"JSON analysis failed, skipping subsequent steps")
                else:
                    print(f"Corresponding JSON file not found: {json_file}")
            else:
                print(f"Pcap parsing failed, skipping subsequent steps")
        
        return success_count

def main():
    """主函数"""
    try:
        tool = SignalingAnalysisTool()
        success = tool.run_analysis()
        
        if success:
            print("\nAll analysis tasks completed! Please check the generated result files.")
        else:
            print("\nErrors occurred during analysis, please check the log information.")
            
    except KeyboardInterrupt:
        print("\n\nUser interrupted operation")
    except Exception as e:
        print(f"\nProgram runtime error: {e}")
        import traceback
        traceback.print_exc()

if __name__ == "__main__":
    main() 